<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>纹理质量诊断工具</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            padding: 20px;
            background: #1e1e1e;
            color: #fff;
        }
        .container {
            max-width: 1200px;
            margin: 0 auto;
        }
        h1 {
            color: #4CAF50;
        }
        .button-group {
            margin: 20px 0;
        }
        button {
            padding: 12px 24px;
            margin: 5px;
            font-size: 16px;
            cursor: pointer;
            border: none;
            border-radius: 4px;
            background: #4CAF50;
            color: white;
            transition: background 0.3s;
        }
        button:hover {
            background: #45a049;
        }
        .output {
            background: #2d2d2d;
            padding: 20px;
            border-radius: 8px;
            margin: 20px 0;
            max-height: 600px;
            overflow-y: auto;
            font-family: 'Consolas', 'Monaco', monospace;
            font-size: 14px;
            line-height: 1.6;
        }
        .success { color: #4CAF50; }
        .warning { color: #ff9800; }
        .error { color: #f44336; }
        .info { color: #2196F3; }
        .section {
            margin: 20px 0;
            padding: 15px;
            background: #333;
            border-radius: 4px;
        }
        .stat-item {
            display: flex;
            justify-content: space-between;
            padding: 5px 0;
            border-bottom: 1px solid #444;
        }
        .instructions {
            background: #2d2d2d;
            padding: 20px;
            border-radius: 8px;
            margin: 20px 0;
            border-left: 4px solid #2196F3;
        }
        .instructions h3 {
            margin-top: 0;
            color: #2196F3;
        }
        .instructions ol {
            padding-left: 20px;
        }
        .instructions li {
            margin: 10px 0;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>🔍 纹理质量诊断工具</h1>
        
        <div class="instructions">
            <h3>📋 使用说明</h3>
            <ol>
                <li>打开编辑器主页面（index.html）</li>
                <li>加载包含贴图的场景</li>
                <li>在浏览器控制台（F12）粘贴并运行下面的诊断代码</li>
                <li>或者直接在主页面控制台输入：<code style="color: #4CAF50;">window.diagnoseTextures()</code></li>
            </ol>
        </div>

        <div class="button-group">
            <button onclick="copyDiagnosticCode()">📋 复制诊断代码</button>
            <button onclick="copyFixCode()">🔧 复制修复代码</button>
            <button onclick="window.open('index.html', '_blank')">🚀 打开编辑器</button>
        </div>

        <div class="section">
            <h3>🔬 诊断代码（在编辑器控制台运行）</h3>
            <pre id="diagnosticCode" style="background: #1e1e1e; padding: 15px; border-radius: 4px; overflow-x: auto;">
// 🔍 纹理质量诊断函数
window.diagnoseTextures = function() {
    console.clear();
    console.log('%c🔍 ===== 纹理质量诊断报告 =====', 'font-size: 16px; font-weight: bold; color: #4CAF50');
    console.log('');
    
    // 检查基础环境
    if (!window.manager) {
        console.error('❌ window.manager 未找到！请确保已加载场景。');
        return;
    }
    
    const scene = window.manager.scene;
    const renderer = window.manager.renderer;
    
    if (!scene || !renderer) {
        console.error('❌ scene 或 renderer 未初始化！');
        return;
    }
    
    // 获取 GPU 信息
    const maxAnisotropy = renderer.capabilities.getMaxAnisotropy();
    console.log(`📊 GPU 最大各向异性级别: ${maxAnisotropy}`);
    console.log('');
    
    // 收集所有纹理
    const textures = new Map();
    let totalMeshes = 0;
    
    scene.traverse((obj) => {
        if (obj.isMesh) {
            totalMeshes++;
            const material = obj.material;
            if (!material) return;
            
            const materials = Array.isArray(material) ? material : [material];
            materials.forEach(mat => {
                ['map', 'normalMap', 'bumpMap', 'aoMap', 'roughnessMap', 'metalnessMap', 'emissiveMap'].forEach(prop => {
                    if (mat[prop] && mat[prop].isTexture) {
                        if (!textures.has(mat[prop].uuid)) {
                            textures.set(mat[prop].uuid, {
                                texture: mat[prop],
                                type: prop,
                                materialName: mat.name || '未命名',
                                meshName: obj.name || '未命名'
                            });
                        }
                    }
                });
            });
        }
    });
    
    console.log(`📷 找到 ${textures.size} 个纹理，应用在 ${totalMeshes} 个 mesh 上\n`);
    
    // 问题统计
    let issues = {
        noMipmaps: 0,
        lowAnisotropy: 0,
        wrongFilter: 0,
        nonPowerOfTwo: 0
    };
    
    // 检查每个纹理
    textures.forEach((info, uuid) => {
        const { texture, type, materialName, meshName } = info;
        
        console.group(`📷 纹理: ${meshName} / ${materialName} / ${type}`);
        
        // 尺寸
        if (texture.image) {
            const isPOT = isPowerOfTwo(texture.image.width) && isPowerOfTwo(texture.image.height);
            console.log(`尺寸: ${texture.image.width} x ${texture.image.height} ${isPOT ? '✅' : '⚠️ 非2的幂'}`);
            if (!isPOT) issues.nonPowerOfTwo++;
        }
        
        // 过滤器
        const minFilterName = getFilterName(texture.minFilter);
        const magFilterName = getFilterName(texture.magFilter);
        const minFilterOK = texture.minFilter === THREE.LinearMipmapLinearFilter;
        const magFilterOK = texture.magFilter === THREE.LinearFilter;
        
        console.log(`minFilter: ${minFilterName} ${minFilterOK ? '✅' : '❌'}`);
        console.log(`magFilter: ${magFilterName} ${magFilterOK ? '✅' : '❌'}`);
        
        if (!minFilterOK || !magFilterOK) issues.wrongFilter++;
        
        // 各向异性
        const anisoOK = texture.anisotropy >= maxAnisotropy;
        console.log(`anisotropy: ${texture.anisotropy} / ${maxAnisotropy} ${anisoOK ? '✅' : '❌'}`);
        if (!anisoOK) issues.lowAnisotropy++;
        
        // Mipmap
        const mipmapOK = texture.generateMipmaps === true;
        console.log(`generateMipmaps: ${texture.generateMipmaps} ${mipmapOK ? '✅' : '❌'}`);
        if (!mipmapOK) issues.noMipmaps++;
        
        console.groupEnd();
        console.log('');
    });
    
    // 输出问题汇总
    console.log('%c📊 ===== 问题汇总 =====', 'font-size: 14px; font-weight: bold; color: #ff9800');
    console.log(`总纹理数: ${textures.size}`);
    console.log(`未启用 Mipmap: ${issues.noMipmaps} ${issues.noMipmaps > 0 ? '❌' : '✅'}`);
    console.log(`各向异性过低: ${issues.lowAnisotropy} ${issues.lowAnisotropy > 0 ? '❌' : '✅'}`);
    console.log(`过滤器错误: ${issues.wrongFilter} ${issues.wrongFilter > 0 ? '❌' : '✅'}`);
    console.log(`非2的幂尺寸: ${issues.nonPowerOfTwo} ${issues.nonPowerOfTwo > 0 ? '⚠️' : '✅'}`);
    console.log('');
    
    const hasIssues = issues.noMipmaps + issues.lowAnisotropy + issues.wrongFilter > 0;
    
    if (hasIssues) {
        console.log('%c⚠️ 发现问题！请运行修复代码：window.fixTextures()', 'font-size: 14px; font-weight: bold; color: #f44336');
    } else {
        console.log('%c✅ 所有纹理设置都是最优的！', 'font-size: 14px; font-weight: bold; color: #4CAF50');
    }
    
    console.log('%c🔍 ===== 诊断完成 =====', 'font-size: 16px; font-weight: bold; color: #4CAF50');
};

// 辅助函数
function isPowerOfTwo(value) {
    return (value & (value - 1)) === 0 && value !== 0;
}

function getFilterName(filter) {
    const filters = {
        [THREE.NearestFilter]: 'NearestFilter',
        [THREE.LinearFilter]: 'LinearFilter',
        [THREE.NearestMipmapNearestFilter]: 'NearestMipmapNearestFilter',
        [THREE.LinearMipmapNearestFilter]: 'LinearMipmapNearestFilter',
        [THREE.NearestMipmapLinearFilter]: 'NearestMipmapLinearFilter',
        [THREE.LinearMipmapLinearFilter]: 'LinearMipmapLinearFilter'
    };
    return filters[filter] || `Unknown(${filter})`;
}

// 运行诊断
window.diagnoseTextures();
            </pre>
        </div>

        <div class="section">
            <h3>🔧 修复代码（如果诊断发现问题）</h3>
            <pre id="fixCode" style="background: #1e1e1e; padding: 15px; border-radius: 4px; overflow-x: auto;">
// 🔧 纹理质量修复函数
window.fixTextures = function() {
    console.clear();
    console.log('%c🔧 ===== 开始修复纹理 =====', 'font-size: 16px; font-weight: bold; color: #4CAF50');
    
    if (!window.manager || !window.manager.scene || !window.manager.renderer) {
        console.error('❌ 环境未初始化！');
        return;
    }
    
    const scene = window.manager.scene;
    const renderer = window.manager.renderer;
    const maxAnisotropy = renderer.capabilities.getMaxAnisotropy();
    
    let fixedCount = 0;
    const processedTextures = new Set();
    
    scene.traverse((obj) => {
        if (obj.isMesh && obj.material) {
            const materials = Array.isArray(obj.material) ? obj.material : [obj.material];
            
            materials.forEach(mat => {
                ['map', 'normalMap', 'bumpMap', 'aoMap', 'roughnessMap', 'metalnessMap', 'emissiveMap'].forEach(prop => {
                    const texture = mat[prop];
                    if (texture && texture.isTexture && !processedTextures.has(texture.uuid)) {
                        processedTextures.add(texture.uuid);
                        
                        // 应用高质量设置
                        texture.generateMipmaps = true;
                        texture.minFilter = THREE.LinearMipmapLinearFilter;
                        texture.magFilter = THREE.LinearFilter;
                        texture.anisotropy = maxAnisotropy;
                        texture.needsUpdate = true;
                        
                        fixedCount++;
                        console.log(`✅ 修复纹理 #${fixedCount}: ${obj.name} / ${mat.name} / ${prop}`);
                    }
                });
                
                mat.needsUpdate = true;
            });
        }
    });
    
    // 触发渲染
    if (window.manager.render) {
        window.manager.render();
    }
    
    console.log('');
    console.log(`%c✅ 修复完成！共修复 ${fixedCount} 个纹理`, 'font-size: 14px; font-weight: bold; color: #4CAF50');
    console.log('%c💡 提示：如果效果仍不理想，请刷新页面重新加载场景', 'color: #2196F3');
    console.log('%c🔧 ===== 修复结束 =====', 'font-size: 16px; font-weight: bold; color: #4CAF50');
};

// 立即运行修复
window.fixTextures();
            </pre>
        </div>

        <div class="output" id="output">
            <div class="info">📝 等待操作...</div>
        </div>
    </div>

    <script>
        function copyDiagnosticCode() {
            const code = document.getElementById('diagnosticCode').textContent;
            navigator.clipboard.writeText(code).then(() => {
                showMessage('✅ 诊断代码已复制到剪贴板！请在编辑器控制台粘贴运行。', 'success');
            });
        }

        function copyFixCode() {
            const code = document.getElementById('fixCode').textContent;
            navigator.clipboard.writeText(code).then(() => {
                showMessage('✅ 修复代码已复制到剪贴板！请在编辑器控制台粘贴运行。', 'success');
            });
        }

        function showMessage(msg, type) {
            const output = document.getElementById('output');
            const className = type === 'success' ? 'success' : type === 'error' ? 'error' : 'info';
            output.innerHTML = `<div class="${className}">${msg}</div>`;
            
            setTimeout(() => {
                output.innerHTML = '<div class="info">📝 等待操作...</div>';
            }, 5000);
        }
    </script>
</body>
</html>

